package com.login.json;

import com.common.constant.JwtProperties;
import com.common.exception.CodeAndMsg;
import com.common.exception.JavaSecurityException;
import com.common.utils.JwtUtil;
import com.login.domain.details.AdminUserDetails;
import com.login.domain.details.WebUserDetails;
import com.login.domain.po.AdminUser;
import com.login.domain.po.WebUser;
import com.login.mapper.AdminUserMapper;
import com.login.mapper.WebUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 路亚
 * @version 0.1
 * @className Json
 * @description
 * @date 2024/12/12 16:00
 * @since jdk11
 */
@Component
@RequiredArgsConstructor
public class JsonAuthenticationProvider implements AuthenticationProvider {

    private final AdminUserMapper adminUserMapper;

    private final WebUserMapper webUserMapper;

    private final JwtProperties jwtProperties;

    private final HttpServletResponse response;


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        JsonAuthenticationToken authenticationToken = null;
        if (authentication instanceof JsonAuthenticationToken){
            authenticationToken = (JsonAuthenticationToken) authentication;
        }
        Integer type = authenticationToken.getType();
        String username = authenticationToken.getUsername();
        String password = authenticationToken.getPassword();
        String token = null;
        if (type == 0){
            AdminUser adminUser = adminUserMapper.selectByUsername(username);
            if (adminUser == null){
                throw new JavaSecurityException(CodeAndMsg.USER_NOT_EXIST);
            }
            if (!new BCryptPasswordEncoder().matches(password, adminUser.getPassword())){
                throw new JavaSecurityException(CodeAndMsg.PASSWORD_ERROR);
            }
            AdminUserDetails adminUserDetails = new AdminUserDetails(adminUser);
            authentication = new JsonAuthenticationToken(adminUserDetails);
            // 返回token
            Map<String, Object> claims = new HashMap<>();
            claims.put(jwtProperties.getAdminIdName(), adminUser.getId());
            token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(), jwtProperties.getAdminTtl(), claims);
            response.setHeader(jwtProperties.getAdminTokenName(), token);
        }else if (type == 1){
            WebUser webUser = webUserMapper.selectByUsername(username);
            if (webUser == null){
                throw new JavaSecurityException(CodeAndMsg.USER_NOT_EXIST);
            }
            if (!new BCryptPasswordEncoder().matches(password, webUser.getAccountPwd())){
                throw new JavaSecurityException(CodeAndMsg.PASSWORD_ERROR);
            }
            WebUserDetails webUserDetails = new WebUserDetails(webUser);
            authentication = new JsonAuthenticationToken(webUserDetails);
            // 返回token
            Map<String, Object> claims = new HashMap<>();
            claims.put(jwtProperties.getWebIdName(), webUser.getId());
            token = JwtUtil.createJWT(jwtProperties.getWebSecretKey(), jwtProperties.getWebTtl(), claims);
            response.setHeader(jwtProperties.getWebTokenName(), token);
        }
        return authentication;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(JsonAuthenticationToken.class);
    }
}
